using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Globalization;

namespace CodeGenerator.Classes
{
   public class GeneratorEntities
    {
        private string mTableName = "";
        private string connStr = "";

       public static string NameSpace = string.Empty;

       public GeneratorEntities(string connectionString, string TableName)
        {
            mTableName = TableName;
            connStr = connectionString;
        }

        public static string PropCaseStartLower(string strText)
        {
            string retVal = PropCase(strText);
            retVal = retVal.Substring(0, 1).ToLower() + retVal.Substring(1, (retVal.Length - 1));
            return retVal;
        }

        public static string PropCase(string strText)
        {
            return new CultureInfo("en").TextInfo.ToTitleCase(strText.ToLower());
        }

        private string DecodeTypeNullable(string sqlType, string nullable)
        {
            string retVal = DecodeType(sqlType);
            string isNull = nullable == "NO" ? string.Empty : "?";

            if (retVal == "string")
            {
            }
            else if (retVal == "byte[]")
            {
            }
            else
            {
                retVal = retVal + isNull;
            }
            return retVal;
        }
        private string DecodeType(string sqlType)
        {
            sqlType = sqlType.ToLower();
            string sysType = "string";
            switch (sqlType)
            {
                case "bigint":
                    sysType = "long";
                    break;
                case "smallint":
                    sysType = "short";
                    break;
                case "int":
                    sysType = "int";
                    break;
                case "uniqueidentifier":
                    sysType = "Guid";
                    break;
                case "smalldatetime":
                case "datetime":
                case "date":
                    sysType = "DateTime";
                    break;
                case "float":
                    sysType = "double";
                    break;
                case "real":
                case "numeric":
                case "smallmoney":
                case "decimal":
                case "money":
                    sysType = "decimal";
                    break;
                case "tinyint":
                    sysType = "byte";
                    break;
                case "bit":
                    sysType = "bool";
                    break;
                case "image":
                case "binary":
                case "varbinary":
                case "timestamp":
                    sysType = "byte[]";
                    break;
            }
            return sysType;
        }


       public string GeneratEntities()
       {
           //string connStr = ConnectionString;
           StringBuilder sql = new StringBuilder();
           SqlConnection conn = new SqlConnection();
           conn.ConnectionString = connStr;
           string cmdTxt = "SELECT * FROM  INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' AND TABLE_NAME='"+mTableName+"'";

           SqlCommand cmd = new SqlCommand();
           cmd.CommandText = cmdTxt;
           cmd.Connection = conn;

           SqlDataAdapter oda = new SqlDataAdapter(cmd);
           DataTable dt = new DataTable();
           oda.Fill(dt);           

           string tName = string.Empty;
           foreach (DataRow dr in dt.Rows)
           {
               tName = PropCaseStartLower(dr["TABLE_NAME"].ToString()).Replace("_", "");

                sql.AppendLine("//===============================================================================");
                sql.AppendLine("// Generated by System");
                sql.AppendLine("//===============================================================================");
                sql.AppendLine("// PURPOSE          : Domain Object Layer");
                sql.AppendLine("// GENERATED DATE   : "+DateTime.Now.ToString());
                sql.AppendLine("//===============================================================================");
                sql.AppendLine("// (c) "+DateTime.Now.Year.ToString());
                sql.AppendLine("//===============================================================================");
                sql.AppendLine("using System;");
                sql.AppendLine("namespace "+NameSpace);
                sql.AppendLine("\t{");


                sql.AppendLine("\t\tpublic partial class " + tName + " : IDisposable");
                sql.AppendLine("\t\t\t{");
                sql.AppendLine("\t\t\t\t#region Constructor");
                sql.AppendLine("\n");
                sql.AppendLine("\t\t\t\tpublic " + tName + "() { }");
                sql.AppendLine("\n");
                sql.AppendLine("\t\t\t\t#endregion");
                sql.AppendLine("\n");

               cmdTxt = @"SELECT 
					TABLE_CATALOG AS [Database],
					TABLE_SCHEMA AS Owner, 
					TABLE_NAME, 
					COLUMN_NAME, 
					ORDINAL_POSITION AS OrdinalPosition, 
					COLUMN_DEFAULT AS DefaultSetting, 
					IS_NULLABLE, 
					DATA_TYPE, 
					CHARACTER_MAXIMUM_LENGTH AS MaxLength, 
					DATETIME_PRECISION AS DatePrecision,
					COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity,
					COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed
					FROM  INFORMATION_SCHEMA.COLUMNS
					WHERE TABLE_NAME = '" +dr["TABLE_NAME"].ToString()+ "' ORDER BY OrdinalPosition ASC"; 

        SqlCommand cmdColl = new SqlCommand();
        cmdColl.CommandText = cmdTxt;
        cmdColl.Connection = conn;

        SqlDataAdapter odaColl = new SqlDataAdapter(cmdColl);
        DataTable dtColl = new DataTable();
        odaColl.Fill(dtColl);

        string collType = string.Empty;
        string propName = string.Empty;
        string isNull = string.Empty;
        foreach (DataRow drColl in dtColl.Rows)
        {
            collType = DecodeTypeNullable(drColl["DATA_TYPE"].ToString(), drColl["IS_NULLABLE"].ToString());
            propName = PropCaseStartLower(drColl["COLUMN_NAME"].ToString()).Replace("_", "");

            sql.AppendLine("\t\t\t\tpublic " + collType + " " + PropCaseStartLower(propName).Replace("_", "") + "{ get; set; }"); 
        }

        sql.AppendLine("\n");
        sql.AppendLine("\t\t\t\t#region IDisposable Members");
        sql.AppendLine("\t\t\t\tpublic void Dispose() { GC.SuppressFinalize(this); } ");
        sql.AppendLine("\t\t\t\t#endregion");
        sql.AppendLine("\n");
        sql.AppendLine("\t\t\t\tpublic partial class Fields ");
        sql.AppendLine("\t\t\t\t{ ");


        foreach (DataRow drColl in dtColl.Rows)
        {
            collType = DecodeType(drColl["DATA_TYPE"].ToString());
            propName = PropCaseStartLower(drColl["COLUMN_NAME"].ToString()).Replace("_", "");

            sql.AppendLine("\t\t\t\t\tpublic static string " + PropCaseStartLower(propName).Replace("_", "") + " { get { return " + "\"" + drColl["COLUMN_NAME"].ToString() + "\"" + "; } }"); 
        }

        sql.AppendLine("\t\t\t\t}");
        sql.AppendLine("\t\t}");
        sql.AppendLine("\t}");

           }

           return sql.ToString();
       }
    }
}
